home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / Python 133 SRC / Tools / modulator / modulator.py < prev    next >
Text File  |  1996-02-20  |  11KB  |  380 lines

  1. #! /usr/local/bin/python
  2. #
  3. # Modulator - Generate skeleton modules.
  4. #
  5. # The user fills out some forms with information about what the module
  6. # should support (methods, objects), names of these things, prefixes to
  7. # use for C code, whether the objects should also support access as numbers,
  8. # etc etc etc.
  9. # When the user presses 'Generate code' we generate a complete skeleton
  10. # module in C.
  11. #
  12. # Alternatively, the selections made can be save to a python sourcefile and
  13. # this sourcefile can be passed on the command line (resulting in the same
  14. # skeleton C code).
  15. #
  16. # Jack Jansen, CWI, October 1994.
  17. #
  18.  
  19. import sys, os
  20. if os.name <> 'mac':
  21.     sys.path.append(os.path.join(os.environ['HOME'], 'src/python/Tools/modulator'))
  22.  
  23. from Tkinter import *
  24. from Tkextra import *
  25. from ScrolledListbox import ScrolledListbox
  26. import sys
  27. import genmodule
  28. import string
  29.  
  30. oops = 'oops'
  31.  
  32. # Check that string is a legal C identifier
  33. def checkid(str):
  34.     if not str: return 0
  35.     if not str[0] in string.letters+'_':
  36.     return 0
  37.     for c in str[1:]:
  38.     if not c in string.letters+string.digits+'_':
  39.         return 0
  40.     return 1
  41.  
  42. def getlistlist(list):
  43.     rv = []
  44.     n = list.size()
  45.     for i in range(n):
  46.     rv.append(list.get(i))
  47.     return rv
  48.     
  49. class UI:
  50.     def __init__(self):
  51.     self.main = Frame()
  52.     self.main.pack()
  53.     self.main.master.title('Modulator: Module view')
  54.     self.cmdframe = Frame(self.main, {'relief':'raised', 'bd':'0.5m',
  55.                       Pack:{'side':'top',
  56.                          'fill':'x'}})
  57.     self.objframe = Frame(self.main, {Pack:{'side':'top', 'fill':'x',
  58.                         'expand':1}})
  59.  
  60.  
  61.     self.check_button = Button(self.cmdframe,
  62.                   {'text':'Check', 'command':self.cb_check,
  63.                    Pack:{'side':'left', 'padx':'0.5m'}})
  64.     self.save_button = Button(self.cmdframe,
  65.                   {'text':'Save...', 'command':self.cb_save,
  66.                    Pack:{'side':'left', 'padx':'0.5m'}})
  67.     self.code_button = Button(self.cmdframe,
  68.                   {'text':'Generate code...',
  69.                    'command':self.cb_gencode,
  70.                    Pack:{'side':'left', 'padx':'0.5m'}})
  71.     self.quit_button = Button(self.cmdframe,
  72.                   {'text':'Quit',
  73.                    'command':self.cb_quit,
  74.                    Pack:{'side':'right', 'padx':'0.5m'}})
  75.  
  76.     self.module = UI_module(self)
  77.     self.objects = []
  78.     self.modified = 0
  79.  
  80.     def run(self):
  81.     self.main.mainloop()
  82.  
  83.     def cb_quit(self, *args):
  84.     if self.modified:
  85.         if not askyn('You have not saved\nAre you sure you want to quit?'):
  86.         return
  87.     sys.exit(0)
  88.  
  89.     def cb_check(self, *args):
  90.     try:
  91.         self.module.synchronize()
  92.         for o in self.objects:
  93.         o.synchronize()
  94.     except oops:
  95.         pass
  96.     
  97.     def cb_save(self, *args):
  98.     try:
  99.         pycode = self.module.gencode('m', self.objects)
  100.     except oops:
  101.         return
  102.  
  103.     fn = askfile('Python file name: ')
  104.     if not fn:
  105.         return
  106.  
  107.     fp = open(fn, 'w')
  108.  
  109.     fp.write(pycode)
  110.     fp.close()
  111.  
  112.     def cb_gencode(self, *args):
  113.     try:
  114.         pycode = self.module.gencode('m', self.objects)
  115.     except oops:
  116.         pass
  117.  
  118.     fn = askfile('C file name: ')
  119.     if not fn:
  120.         return
  121.  
  122.     fp = open(fn, 'w')
  123.  
  124.     try:
  125.         exec pycode
  126.     except:
  127.         message('An error occurred:-)')
  128.         return
  129.     genmodule.write(fp, m)
  130.     fp.close()
  131.  
  132. class UI_module:
  133.     def __init__(self, parent):
  134.     self.parent = parent
  135.     self.frame = Frame(parent.objframe, {'relief':'raised', 'bd':'0.2m',
  136.                          Pack:{'side':'top',
  137.                            'fill':'x'}})
  138.     self.f1 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
  139.                        'fill':'x'}})
  140.     self.f2 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
  141.                        'fill':'x'}})
  142.     self.f3 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
  143.                        'fill':'x'}})
  144.     self.f4 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
  145.                        'fill':'x'}})
  146.  
  147.     self.l1 = Label(self.f1, {'text':'Module:', Pack:{'side':'left',
  148.                             'padx':'0.5m'}})
  149.     self.name_entry = Entry(self.f1, {'relief':'sunken',
  150.                   Pack:{'side':'left', 'padx':'0.5m', 'expand':1}})
  151.     self.l2 = Label(self.f1, {'text':'Abbrev:', Pack:{'side':'left',
  152.                             'padx':'0.5m'}})
  153.     self.abbrev_entry = Entry(self.f1, {'relief':'sunken', 'width':5,
  154.                   Pack:{'side':'left', 'padx':'0.5m'}})
  155.  
  156.     self.l3 = Label(self.f2, {'text':'Methods:', Pack:{'side':'left',
  157.                             'padx':'0.5m'}})
  158.     self.method_list = ScrolledListbox(self.f2, {'relief':'sunken','bd':2,
  159.                       Pack:{'side':'left', 'expand':1,
  160.                         'padx':'0.5m', 'fill':'both'}})
  161.  
  162.     self.l4 = Label(self.f3, {'text':'Add method:', Pack:{'side':'left',
  163.                                   'padx':'0.5m'}})
  164.     self.method_entry = Entry(self.f3, {'relief':'sunken',
  165.                  Pack:{'side':'left', 'padx':'0.5m', 'expand':1}})
  166.     self.method_entry.bind('<Return>', self.cb_method)
  167.     self.delete_button = Button(self.f3, {'text':'Delete method',
  168.                           'command':self.cb_delmethod,
  169.                           Pack:{'side':'left',
  170.                             'padx':'0.5m'}})
  171.  
  172.     self.newobj_button = Button(self.f4, {'text':'new object',
  173.                           'command':self.cb_newobj,
  174.                           Pack:{'side':'left',
  175.                             'padx':'0.5m'}})
  176.     
  177.     def cb_delmethod(self, *args):
  178.     list = self.method_list.curselection()
  179.     for i in list:
  180.         self.method_list.delete(i)
  181.     
  182.     def cb_newobj(self, *arg):
  183.     self.parent.objects.append(UI_object(self.parent))
  184.  
  185.     def cb_method(self, *arg):
  186.     name = self.method_entry.get()
  187.     if not name:
  188.         return
  189.     self.method_entry.delete('0', 'end')
  190.     self.method_list.insert('end', name)
  191.  
  192.     def synchronize(self):
  193.     n = self.name_entry.get()
  194.     if not n:
  195.         message('Module name not set')
  196.         raise oops
  197.     if not checkid(n):
  198.         message('Module name not an identifier:\n'+n)
  199.         raise oops
  200.     if not self.abbrev_entry.get():
  201.         self.abbrev_entry.insert('end', n)
  202.     m = getlistlist(self.method_list)
  203.     for n in m:
  204.         if not checkid(n):
  205.         message('Method name not an identifier:\n'+n)
  206.         raise oops
  207.         
  208.     def gencode(self, name, objects):
  209.     rv = ''
  210.     self.synchronize()
  211.     for o in objects:
  212.         o.synchronize()
  213.     onames = []
  214.     for i in range(len(objects)):
  215.         oname = 'o'+`i+1`
  216.         rv = rv + objects[i].gencode(oname)
  217.         onames.append(oname)
  218.     rv = rv + (name+' = genmodule.module()\n')
  219.     rv = rv + (name+'.name = '+`self.name_entry.get()`+'\n')
  220.     rv = rv + (name+'.abbrev = '+`self.abbrev_entry.get()`+'\n')
  221.     rv = rv + (name+'.methodlist = '+`getlistlist(self.method_list)`+'\n')
  222.     rv = rv + (name+'.objects = ['+string.joinfields(onames, ',')+']\n')
  223.     rv = rv + ('\n')
  224.     return rv
  225.     
  226. object_number = 0
  227.  
  228. class UI_object:
  229.     def __init__(self, parent):
  230.     global object_number
  231.  
  232.     object_number = object_number + 1
  233.     self.num = object_number
  234.     self.vpref = 'o'+`self.num`+'_'
  235.     self.frame = Toplevel(parent.objframe)
  236. #    self.frame.pack()
  237.     self.frame.title('Modulator: object view')
  238. #    self.frame = Frame(parent.objframe, {'relief':'raised', 'bd':'0.2m',
  239. #                         Pack:{'side':'top',
  240. #                           'fill':'x'}})
  241.     self.f1 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
  242.                        'fill':'x'}})
  243.     self.f2 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
  244.                        'fill':'x'}})
  245.     self.f3 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
  246.                        'fill':'x'}})
  247.     self.f4 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m',
  248.                        'fill':'x'}})
  249.     
  250.  
  251.     self.l1 = Label(self.f1, {'text':'Object:', Pack:{'side':'left',
  252.                             'padx':'0.5m'}})
  253.     self.name_entry = Entry(self.f1, {'relief':'sunken',
  254.                   Pack:{'side':'left', 'padx':'0.5m', 'expand':1}})
  255.     self.l2 = Label(self.f1, {'text':'Abbrev:', Pack:{'side':'left',
  256.                             'padx':'0.5m'}})
  257.     self.abbrev_entry = Entry(self.f1, {'relief':'sunken', 'width':5,
  258.                   Pack:{'side':'left', 'padx':'0.5m'}})
  259.  
  260.     self.l3 = Label(self.f2, {'text':'Methods:', Pack:{'side':'left',
  261.                             'padx':'0.5m'}})
  262.     self.method_list = ScrolledListbox(self.f2, {'relief':'sunken','bd':2,
  263.                       Pack:{'side':'left', 'expand':1,
  264.                         'padx':'0.5m', 'fill':'both'}})
  265.  
  266.     self.l4 = Label(self.f3, {'text':'Add method:', Pack:{'side':'left',
  267.                                   'padx':'0.5m'}})
  268.     self.method_entry = Entry(self.f3, {'relief':'sunken',
  269.                  Pack:{'side':'left', 'padx':'0.5m', 'expand':1}})
  270.     self.method_entry.bind('<Return>', self.cb_method)
  271.     self.delete_button = Button(self.f3, {'text':'Delete method',
  272.                           'command':self.cb_delmethod,
  273.                           Pack:{'side':'left',
  274.                             'padx':'0.5m'}})
  275.  
  276.  
  277.     self.l5 = Label(self.f4, {'text':'functions:',
  278.                   Pack:{'side':'left',
  279.                     'padx':'0.5m'}})
  280.     self.f5 = Frame(self.f4, {Pack:{'side':'left', 'pady':'0.5m',
  281.                        'fill':'both'}})
  282.     self.l6 = Label(self.f4, {'text':'Types:',
  283.                   Pack:{'side':'left', 'padx':'0.5m'}})
  284.     self.f6 = Frame(self.f4, {Pack:{'side':'left', 'pady':'0.5m',
  285.                        'fill':'x'}})
  286.     self.funcs = {}
  287.     for i in genmodule.FUNCLIST:
  288.         vname = self.vpref+i
  289.         self.f5.setvar(vname, 0)
  290.         b = Checkbutton(self.f5, {'variable':vname, 'text':i,
  291.                       Pack:{'side':'top', 'pady':'0.5m',
  292.                         'anchor':'w','expand':1}})
  293.         self.funcs[i] = b
  294.     self.f5.setvar(self.vpref+'new', 1)
  295.  
  296.     self.types = {}
  297.     for i in genmodule.TYPELIST:
  298.         vname = self.vpref + i
  299.         self.f6.setvar(vname, 0)
  300.         b = Checkbutton(self.f6, {'variable':vname, 'text':i,
  301.                       Pack:{'side':'top', 'pady':'0.5m',
  302.                         'anchor':'w'}})
  303.         self.types[i] = b
  304.     
  305.     def cb_method(self, *arg):
  306.     name = self.method_entry.get()
  307.     if not name:
  308.         return
  309.     self.method_entry.delete('0', 'end')
  310.     self.method_list.insert('end', name)
  311.  
  312.     def cb_delmethod(self, *args):
  313.     list = self.method_list.curselection()
  314.     for i in list:
  315.         self.method_list.delete(i)
  316.     
  317.     def synchronize(self):
  318.     n = self.name_entry.get()
  319.     if not n:
  320.         message('Object name not set')
  321.         raise oops
  322.     if not self.abbrev_entry.get():
  323.         self.abbrev_entry.insert('end', n)
  324.     n = self.abbrev_entry.get()
  325.     if not checkid(n):
  326.         message('Abbreviation not an identifier:\n'+n)
  327.         raise oops
  328.     m = getlistlist(self.method_list)
  329.     for n in m:
  330.         if not checkid(n):
  331.         message('Method name not an identifier:\n'+n)
  332.         raise oops
  333.     if m:
  334.         self.f5.setvar(self.vpref+'tp_getattr', 1)
  335.     pass
  336.     
  337.     def gencode(self, name):
  338.     rv = ''
  339.     rv = rv + (name+' = genmodule.object()\n')
  340.     rv = rv + (name+'.name = '+`self.name_entry.get()`+'\n')
  341.     rv = rv + (name+'.abbrev = '+`self.abbrev_entry.get()`+'\n')
  342.     rv = rv + (name+'.methodlist = '+`getlistlist(self.method_list)`+'\n')
  343.     fl = []
  344.     for fn in genmodule.FUNCLIST:
  345.         vname = self.vpref + fn
  346.         if self.f5.getvar(vname) == '1':
  347.         fl.append(fn)
  348.     rv = rv + (name+'.funclist = '+`fl`+'\n')
  349.  
  350.     fl = []
  351.     for fn in genmodule.TYPELIST:
  352.         vname = self.vpref + fn
  353.         if self.f5.getvar(vname) == '1':
  354.         fl.append(fn)
  355.         
  356.     rv = rv + (name+'.typelist = '+`fl`+'\n')
  357.  
  358.     rv = rv + ('\n')
  359.     return rv
  360.     
  361.  
  362. def main():
  363.     if len(sys.argv) < 2:
  364.     ui = UI()
  365.     ui.run()
  366.     elif len(sys.argv) == 2:
  367.     fp = open(sys.argv[1])
  368.     pycode = fp.read()
  369.     try:
  370.         exec pycode
  371.     except:
  372.         sys.stderr.write('An error occurred:-)\n')
  373.         sys.exit(1)
  374.     genmodule.write(sys.stdout, m)
  375.     else:
  376.     sys.stderr.write('Usage: modulator [file]\n')
  377.     sys.exit(1)
  378.     
  379. main()
  380.